package web.services;

import web.dao.ToolDao;
import web.util.StringOperateUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by Administrator on 2016/7/8.
 */

@Service
public class ToolService {
    @Autowired
    private ToolDao toolDao;
    @Autowired
    private LocationService locationService;
    @Autowired
    private LuceneSearchService luceneSearchService;


    //插入缓存type
    public final static int FUNCTIONONE=1; //招标单位查询供应商
    public final static int FUNCTIONTWO=2;  //产品查询供应商
    public final static int WINBIDCOMPANYNEWS=3;  //中标公司查中标信息
    public final static int SUBSCRIBERCONACT=4; //查询使用单位联系方式


    /**
     * 查询缓存数据
     * @param key
     * @param province
     * @param type
     * @return
     */
    public Map<String,Object> findIdJson(String key, int province, int type){
        return toolDao.findIdJson(key,province,type);
    }
    /**
     * 添加缓存数据
     * @param key
     * @param provinceId
     * @param type
     */
    public void insertToolCache(List<Map<String,Object>>list ,String key ,int provinceId ,int type){
        toolDao.insertToolCache(JSONObject.toJSONString(list),key, provinceId, type);
    }


    /**
     * 查询success_news_num 中与subscriber相关的供应商
     * @param subscriber
     * @return
     */
    public List<Map<String,Object>> findWinBidCompanyBySubscriber(String subscriber){
        List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();
        List<Map<String,Object>> newsList=new ArrayList<Map<String, Object>>();
        int num=1;
        String []strings=StringOperateUtil.reString(subscriber).trim().split(" ");
        for (String s : strings) {
            Map<String, Object> idJson = findIdJson(s,0, ToolService.FUNCTIONONE);
            if(idJson.get("id_json")==null) {
                List<Map<String,Object>> list2=new ArrayList<Map<String, Object>>();
                do {
                    try {
                        List<Map<String,Object>>list1=toolDao.findWinBidCompanyBySubscriber(StringOperateUtil.returnKey(subscriber), num);
                        //获取供应商数据
                        list.addAll(list1);

//                        插入数据库
                        list2.addAll(list1);
                    } catch (BadSqlGrammarException e) {
                        break;
                    }
                    num++;
                } while (true);
                List<Map<String,Object>> newsListCs=new ArrayList<Map<String, Object>>();
                updateList(list2,newsListCs);
                insertToolCache(newsListCs,s, 0, ToolService.FUNCTIONONE);
            }else{
                list.addAll(( List<Map<String,Object>> ) JSONObject.parse(idJson.get("id_json")+""));
            }
        }
        //信息去重，并获取ID
        updateList(list,newsList);
        return newsList;

    }


    /**
     * 通过多个已知中标表与ID，查询出多条数据
     * @param ids
     * @return
     */
    public List<Map<String,Object>> findListSuccessfulNews(String[]ids){
        List<Map<String,Object>> list = new ArrayList<Map<String, Object>>();
        for (String s : ids) {
            String []strings=StringOperateUtil.reJson(s).split("_");
            list.add(toolDao.findSuccessfulNews(Integer.parseInt(strings[0]),strings[1]));
        }
        return list;
    }

    /**
     * 通过产品名称keyWord，查询相关的招中标公司
     * @param keyWord
     * @param province
     * @return
     */
    public List<Map<String,Object>> findWinBidCompanyByKeyWord(String keyWord,int province){
        List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();
        List<Map<String,Object>> newsList=new ArrayList<Map<String, Object>>();
        int num=1;
        String []strings=StringOperateUtil.reString(keyWord).trim().split(" ");
        for (String s : strings) {
            Map<String,Object> idJson=findIdJson(s,province,ToolService.FUNCTIONTWO);
            if(idJson.get("id_json")==null) {
                List<Map<String,Object>> list2=new ArrayList<Map<String, Object>>();
                do {
                    try {
                        List<Map<String,Object>> list1=toolDao.findWinBidCompanyByKeyWord(StringOperateUtil.returnKey(s), num, province);
                        list.addAll(list1);
                        list2.addAll(list1);

                    } catch (BadSqlGrammarException e) {
                        break;
                    }
                    num++;
                } while (true);
                List<Map<String,Object>> newsListCs=new ArrayList<Map<String, Object>>();
                updateListKey(list2,newsListCs);
                // 插入数据库
                insertToolCache(newsListCs, s, province, ToolService.FUNCTIONTWO);
            }else{
                list.addAll(( List<Map<String,Object>> )JSONObject.parse(idJson.get("id_json")+""));
            }
        }



        updateListKey(list,newsList);
        return newsList;
    }

    /**
     * 修改重复数据
     * @param list
     * @param newsList
     * @return
     */
    public List<Map<String,Object>> updateList(List<Map<String,Object>> list, List<Map<String,Object>> newsList){
        Set<String>set=new HashSet<String>();
        for (Map<String,Object> map : list) {
            String key=(map.get("winBidCompany")+""+map.get("subscriber")).trim();
            if(key.length()>100){
                continue;
            }
            if(set.contains(key)){
                for(Map<String,Object>maps:newsList){
                    if(maps.get("key").equals(key)){
                        ((List<String>)maps.get("ids")).add(map.get("id")+"_"+map.get("num"));
                        break;
                    }
                }
            }else{
                Map<String,Object>mapNews=new HashMap<String, Object>();
                mapNews.put("key",key);
                mapNews.put("subscriber",map.get("subscriber"));
                mapNews.put("winBidCompany",map.get("winBidCompany"));
                List<String>ids=new ArrayList<String>();
                ids.add(map.get("id")+"_"+map.get("num"));
                mapNews.put("ids",ids);
                newsList.add(mapNews);
                set.add(key);
            }
        }
        return newsList;
    }

    public List<Map<String,Object>> updateListKey(List<Map<String,Object>> list, List<Map<String,Object>> newsList){
        //中标单位计数
        Set<String>set=new HashSet<String>();
        for (Map<String,Object> map : list) {
            String winBidCompany=map.get("winBidCompany").toString();
            if(set.contains(winBidCompany)){
                for(Map<String,Object>maps:newsList){
                    if(maps.get("winBidCompany").equals(winBidCompany)){
                        ((List<String>)maps.get("ids")).add(map.get("id")+"_"+map.get("num"));
                        maps.put("num",Integer.parseInt(maps.get("num").toString())+1);
                        break;
                    }
                }
            }else{
                Map<String,Object>mapNews=new HashMap<String, Object>();
                List<String>ids=new ArrayList<String>();
                ids.add(map.get("id")+"_"+map.get("num"));
                mapNews.put("ids",ids);
                mapNews.put("num",1);
                mapNews.put("winBidCompany",winBidCompany);
                newsList.add(mapNews);
                set.add(winBidCompany);
            }
        }
        return newsList;
    }


    /**
     * 通过使用单位查询出该单位所有联系人与联系电话
     * @param subscriber
     * @return
     */
    public List<Map<String,Object>> findAllSubscriberContactBySubscriber(String subscriber){

        List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();

        Map<String,Object> idJson=findIdJson(subscriber,0,ToolService.SUBSCRIBERCONACT);
        if(idJson.get("id_json")!=null){
            return (List<Map<String,Object>>)JSONObject.parse(idJson.get("id_json").toString());
        }
//        实时查询招标单位联系方式
//        List<String> listDistrict=locationService.getLocationList();
//        for (String district : listDistrict) {
//            list.addAll(toolDao.findAllSubscriberContactBySubscriber(subscriber,district));
//        }
//        insertToolCache(list,subscriber,0,ToolService.SUBSCRIBERCONACT);
        return list;
    }

    /**
     * 查询success_news_num 中与subscriber相关的供应商
     * @param subscriber
     * @param type 0：普通查询数据 1：定期更新数据
     * @return
     */
    public List<Map<String,Object>> findWinBidCompanyBySubscriber(String subscriber,int type){
        List<Map<String,Object>> list=new ArrayList<Map<String, Object>>();
        List<Map<String,Object>> newsList=new ArrayList<Map<String, Object>>();
        int num=1;
        String []strings=StringOperateUtil.reString(subscriber).trim().split(" ");
        try {
            for (String s : strings) {
                Map<String, Object> idJson=new HashMap<String, Object>();
                if(type==0) {
                    idJson = findIdJson(s, 0, ToolService.FUNCTIONONE);
                }
                if(idJson.get("id_json") != null){
                    list.addAll((List<Map<String, Object>>) JSONObject.parse(idJson.get("id_json") + ""));
                }
            }
            //信息去重，并获取ID
            updateList(list, newsList);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;

    }

    public List<Map<String,Object>> findWinBidCompanyBySubscriberNews(String subscriber){
        List<Map<String,Object>> list=findWinBidCompanyBySubscriber(subscriber,0);
        List<Map<String,Object>>listWinBidCompany=new ArrayList<Map<String, Object>>();
        for (Map<String, Object> map : list) {
            Map<String,Object> mapWinBid = new HashMap<String, Object>();
            String winBidCompany=map.get("winBidCompany").toString();
            //处理特殊字符
            winBidCompany=StringOperateUtil.reStrings(winBidCompany);
            if(listWinBidCompany.contains(winBidCompany)) {
                continue;
            }
            mapWinBid.put("winBidCompany",winBidCompany);
            mapWinBid.put("ids",map.get("ids"));
            listWinBidCompany.add(mapWinBid);
        }
        return listWinBidCompany;

    }
    // 用于分数计算
    //四合一联系人与电话查询
    public final static int CONTACTTYPE=1;
    //四合一中标信息查询
    public final static int SUCCESSNEWSTYPE=2;
    //四合一中标公司查询
    public final static int SUCCESSCOMPANYTYPE=3;
    /**
     * 获取该招标单位所有中标信息
     * @param subscriber
     * @param titleKey
     * @return
     */
    public List<Map<String,Object>> findSuccessNewsBySubscriber(String subscriber,String titleKey,int type){
        List<Map<String,Object>> list=findWinBidCompanyBySubscriber(subscriber,0);
        List<String>listIds=new ArrayList<String>();
//        将所有中标信息Id都存入list中
        for (Map<String, Object> map : list) {
            if(subscriber.equals(map.get("subscriber"))){
                if(map.get("ids")==null){
                    return findSuccessNewsBySubscriber(subscriber ,titleKey ,type);
                }else {
                    listIds.addAll((List<String>)map.get("ids"));
                }
            }


        }

        list.clear();

//        通过ID找到标题ID等其他信息
//        long long1 =System.currentTimeMillis();
        for (String id : listIds) {
            String [] str=id.split("_");
            list.add(toolDao.findSuccessfulNews(Integer.parseInt(str[0]),str[1]));
        }
//        System.out.println("耗时："+(System.currentTimeMillis()-long1));
//      查询中标信息分数
        Map<Long,Double> listScore=luceneSearchService.getScoreCompute(list,titleKey);

        for (Map<String, Object> map : list) {
            Double score=listScore.get(Long.parseLong(map.get("id").toString()));
            if(score==null){
                score=0.0;
            }
            map.put("score",score);
        }

        List<Map<String, Object>> listNews=new ArrayList<Map<String, Object>>();
        //       将相同数据分数相加
        if(type==ToolService.SUCCESSCOMPANYTYPE)   {
            listNews= newsScoreSum(list, type);
        }else if(type==ToolService.SUCCESSNEWSTYPE){
            listNews=list;
        }

        Collections.sort(listNews,new Comparator<Map<String,Object>>() {
            public int compare(Map<String,Object> o1, Map<String,Object> o2) {
                int map1value =(int)(Double.parseDouble(o1.get("score")+"")*100000000);
                int map2value =(int)(Double.parseDouble( o2.get("score")+"")*100000000);
                return map2value - map1value;
            }
        });
        return listNews;
    }

    /**
     * 将相同数据分数相加
     * @return
     */
    public List<Map<String,Object>> newsScoreSum(List<Map<String,Object>>list , int type){
        List<Map<String,Object>> listNews=new ArrayList<Map<String, Object>>();
        if(type==ToolService.CONTACTTYPE){
            for (Map<String, Object> map : list) {
//                listNews是否已存在与list相同数据
                boolean b=false;
                for (Map<String, Object> listNew : listNews) {
//                    联系人与联系电话相同则表明存在
                    if(map.get("subscriber_contact").toString().equals(listNew.get("subscriber_contact").toString())
                            &&map.get("subscriber_phone").toString().equals(listNew.get("subscriber_phone").toString())){
                        if(map.get("score")==null){
                            listNew.put("score",0);
                        }else {
                            listNew.put("score", Double.parseDouble(map.get("score").toString())
                                    + Double.parseDouble(listNew.get("score").toString()));
                        }
                        b=true;
                        break;
                    }
//                    不存在则需要添加该数据
                }
                if(!b){
                    listNews.add(map);
                }
            }
        }else if(type==ToolService.SUCCESSCOMPANYTYPE){
            for (Map<String, Object> map : list) {
//                listNews是否已存在与list相同数据
                boolean b=false;
                for (Map<String, Object> listNew : listNews) {
//                    联系人与联系电话相同则表明存在
                    if(map.get("winBidCompany").toString().equals(listNew.get("winBidCompany").toString())){
//                        计数，中标公司中标多少次
                        listNew.put("num",Integer.parseInt(listNew.get("num").toString())+1);
                        List<Map<String,Object>>listUrl= (List<Map<String,Object>>)listNew.get("listUrl");
                        Map<String,Object> maps=new HashMap<String, Object>();
                        maps.put("url",map.get("url")+"");
                        maps.put("title",map.get("title"));
                        listUrl.add(maps);

                        if(map.get("score")==null){
                            listNew.put("score",0);
                        }else {
                            listNew.put("score", Double.parseDouble(map.get("score").toString())
                                    + Double.parseDouble(listNew.get("score").toString()));
                        }
                        b=true;
                        break;
                    }
//                    不存在则需要添加该数据
                }
                if(!b){
                    List<Map<String,Object>>listUrl=new ArrayList<Map<String,Object>>();
                    Map<String,Object> maps=new HashMap<String, Object>();
                    maps.put("url",map.get("url")+"");
                    maps.put("title",map.get("title"));
                    listUrl.add(maps);
                    map.put("listUrl",listUrl);
                    map.put("num",1);
                    listNews.add(map);
                }
            }
        }
        return listNews;
    }

    /**
     * 查询招标单位
     * @param districtNewsId
     * @param province_id
     * @return
     */
    public Map<String,Object> findSubscriberById(String districtNewsId,String province_id){
        return toolDao.findSubscriberById(districtNewsId,province_id);
    }
    /**
     * 获取联系方式，并对联系方式经行排序
     * @param subscriber
     * @param titleKey
     * @return
     */
    public List<Map<String,Object>> findAllSubscriberContact(String subscriber,String titleKey){
        List<Map<String,Object>> list=findAllSubscriberContactBySubscriber(subscriber);
        Map<Long,Double> listScore=luceneSearchService.getScoreCompute(list,titleKey);
        for (Map<String, Object> map : list) {

            Double score=listScore.get(Long.parseLong(map.get("id").toString()));
            if(score==null){
                score=0.0;
            }
            map.put("score",score);
        }

//       将相同数据分数相加
        List<Map<String,Object>>listNews =newsScoreSum(list,ToolService.CONTACTTYPE);

        Collections.sort(listNews,new Comparator<Map<String,Object>>() {
            public int compare(Map<String,Object> o1, Map<String,Object> o2) {
                int map1value =(int)(Double.parseDouble(o1.get("score")+"")*100000000);
                int map2value =(int)(Double.parseDouble( o2.get("score")+"")*100000000);
                return map2value - map1value;
            }
        });
        return listNews;
    }
}
